package com.tc.filters;

import com.tc.client.ItemCheck;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Autowired
    private ItemCheck itemCheck;
    @Autowired
    private ExecutorService executorService;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //优先统一添加响应头
        exchange.getResponse()
                .getHeaders()
                .add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        //获取请求
        ServerHttpRequest request = exchange.getRequest();
        //判断请求路径是否需要身份验证,如果是登陆请求直接放行
        if(request.getPath().toString().contains("/login")
           || request.getPath().toString().contains("/getRecommendShop")
           || request.getPath().toString().contains("/socket")){
            return chain.filter(exchange);
        }
        //剩下的都是要验证openid的真伪,调用校验服务
        Boolean res;
//        CompletableFuture<Boolean> future=CompletableFuture.supplyAsync(()->
//            itemCheck.checkOpenId(request.getHeaders().getFirst("openId")+":"+request.getHeaders().getFirst("id")
//        );
        //gateway只支持异步调用
        Future<Boolean> future=executorService.submit(()->
                itemCheck.checkOpenId(
                        request.getHeaders().getFirst("openId")
                                +":"+
                                request.getHeaders().getFirst("id")
                ));
        //获取返回结果
        try{
            //最多等待一秒
            res=future.get(1, TimeUnit.SECONDS);
        } catch (Exception e) {
            log.info("校验openid超时");
            e.printStackTrace();
            //说明check服务出现异常,返回401
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        if(res){
            //能进入说明openid为真,继续进入下一个过滤器
            return chain.filter(exchange);
        }
        //到这就说明不能openid错误，不能放行
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().setComplete();

    }

    //实现ordered接口是为了指定过滤器的执行顺序，必须要在转发过滤器(最后的过滤器)前执行
    @Override
    public int getOrder() {
        //转发过滤器的order就是int的最大值
        return 0;
    }
}
